home *** CD-ROM | disk | FTP | other *** search
/ Pascal Super Library / Pascal Super Library (CW International)(1997).bin / FILE_UTL / QMOVE / QMOVE.PAS < prev   
Pascal/Delphi Source File  |  1989-01-31  |  9KB  |  322 lines

  1. {$V-,S-,R-,I-}
  2. {--------------------------------------------------------------}
  3. {                                                              }
  4. {             Saved as: QMOVE.PAS                              }
  5. {               Author: Pat Anderson                           }
  6. {             Language: TP5                                    }
  7. {              Purpose: File moving utility                    }
  8. {        Last modified: Monday, 1-30-1989                      }
  9. {                                                              }
  10. {--------------------------------------------------------------}
  11.  
  12. PROGRAM QMove;
  13.  
  14. USES
  15.   Crt,
  16.   Dos,
  17.   Exists40;
  18.  
  19. TYPE
  20.   Str2  = string[2];
  21.   Str64 = string[64];
  22.  
  23. VAR
  24.   CurrentDrive,
  25.   SourceDrive,
  26.   DestinationDrive       : Str2;
  27.   SourceFiles,
  28.   DestinationDir,
  29.   SourcePath             : DirStr;
  30.   SourceName             : NameStr;
  31.   SourceExt              : ExtStr;
  32.   OnSameDrive            : boolean;
  33.   DirInfo                : SearchRec;
  34.   DiskBuf                : array [1..16384] of byte;
  35.   BytesRead,
  36.   BytesWritten           : integer;
  37.   OverwriteFile          : boolean;
  38.  
  39. PROCEDURE ShowCorrectUsage;
  40.   BEGIN
  41.     WriteLn;
  42.     WriteLn ('Usage:');
  43.     WriteLn;
  44.     WriteLn ('  QMOVE SourceFile(s) DestinationDir');
  45.     WriteLn;
  46.     WriteLn ('Full paths may be specified for both Source and Destination.');
  47.     WriteLn ('Wildcards ''?'' and ''*'' are permitted in SourceFile(s).');
  48.     WriteLn ('If DestinationDir is not specified, SourceFile(s) will be moved');
  49.     WriteLn ('to current directory of logged drive.');
  50.     WriteLn;
  51.     Halt (1);
  52.   END;
  53.  
  54. FUNCTION ToUpper (S : string) : string;
  55.   VAR
  56.     i : byte;
  57.   BEGIN
  58.     FOR i := 1 TO Length (S) DO
  59.       S[i] := UpCase (S[i]);
  60.     ToUpper := S;
  61.   END; {of function ToUpper}
  62.  
  63. FUNCTION GetCurrentDrive : Str2;
  64.   VAR
  65.     S : string;
  66.   BEGIN
  67.     GetDir (0,S);
  68.     GetCurrentDrive := Copy (S,1,2);
  69.   END; {of function GetCurrentDrive}
  70.  
  71. PROCEDURE ConfirmOverWrite;
  72.   VAR
  73.     Answer : char;
  74.   BEGIN
  75.     WriteLn;
  76.     WriteLn
  77.       ('File ',DirInfo.Name,' in ',DestinationDir,' will be OVERWRITTEN');
  78.     WriteLn ('Do you want to overwrite the existing file? (Y/N)');
  79.     REPEAT
  80.       Answer := UpCase (ReadKey);
  81.     UNTIL Answer IN ['Y','N'];
  82.     IF Answer = 'Y' THEN
  83.       OverwriteFile := TRUE
  84.     ELSE
  85.       OverwriteFile := FALSE;
  86.   END;
  87.  
  88. PROCEDURE MoveByCopyingAndDeleting;
  89.   VAR
  90.     SourceFile,
  91.     DestinationFile : file;
  92.     ByteCount : word;
  93.  
  94.   BEGIN
  95.     FindFirst (SourceFiles,AnyFile,DirInfo);
  96.     WriteLn;
  97.  
  98.     WHILE DosError = 0 DO
  99.       BEGIN
  100.         IF (DirInfo.Attr <> Directory) AND (DirInfo.Attr <> VolumeID) THEN
  101.           BEGIN
  102.             IF FileExists (DestinationDir + DirInfo.Name) THEN
  103.               ConfirmOverwrite;
  104.             IF OverwriteFile THEN
  105.               BEGIN
  106.                 Write
  107.                   ('Moving ', SourcePath + DirInfo.Name);
  108.                 GotoXY (35,WhereY);
  109.                 Write ('to');
  110.                 GotoXY (45,WhereY);
  111.                 WriteLn (DestinationDir + DirInfo.Name);
  112.                 Assign (SourceFile, SourcePath + DirInfo.Name);
  113.                 Reset (SourceFile,1);
  114.                 Assign (DestinationFile, DestinationDir + DirInfo.Name);
  115.                 Rewrite (DestinationFile,1);
  116.  
  117.                 {Copy algorithm from Tom Swan,
  118.                  Mastering Turbo Pascal 4.0, p. 161}
  119.                 REPEAT
  120.                   BlockRead (SourceFile, DiskBuf,
  121.                              SizeOf(DiskBuf), BytesRead);
  122.                   IF BytesRead > 0 THEN
  123.                     BEGIN
  124.                       BlockWrite (DestinationFile, DiskBuf,
  125.                                   BytesRead, BytesWritten);
  126.                       IF BytesRead <> BytesWritten THEN
  127.                         BEGIN
  128.                           {Code to inform user of disk write
  129.                            error, close files and quit}
  130.                         END;
  131.                     END;
  132.                 UNTIL BytesRead = 0;
  133.                 Close (SourceFile);
  134.                 Erase (SourceFile);
  135.                 Close (DestinationFile);
  136.               END; {IF OverwriteFile}
  137.           END; {IF not Directory or Volume ID}
  138.         FindNext (DirInfo);
  139.     END; {while}
  140.   END;
  141.  
  142. PROCEDURE MoveByRenaming;
  143.   VAR
  144.     F, ZapF : file;
  145.     SkipFile : boolean;
  146.   BEGIN
  147.     SkipFile := FALSE;
  148.     FindFirst (SourceFiles,AnyFile,DirInfo);
  149.     WriteLn;
  150.  
  151.     WHILE DosError = 0 DO
  152.       BEGIN
  153.         IF (DirInfo.Attr <> Directory) AND (DirInfo.Attr <> VolumeID) THEN
  154.           BEGIN
  155.             IF FileExists (DestinationDir + DirInfo.Name) THEN
  156.               BEGIN
  157.                 ConfirmOverwrite;
  158.                 IF OverWritefile THEN
  159.                   BEGIN
  160.                     Assign (ZapF, DestinationDir + DirInfo.Name);
  161.                     Erase (ZapF);
  162.                     SkipFile := FALSE;
  163.                   END
  164.                 ELSE
  165.                   SkipFile := TRUE;
  166.               END; {IF FileExists}
  167.  
  168.             IF NOT SkipFile THEN
  169.               BEGIN
  170.                 Write
  171.                   ('Moving ', SourcePath + DirInfo.Name);
  172.                 GotoXY (35, WhereY);
  173.                 Write ('to');
  174.                 GotoXY (45, WhereY);
  175.                 WriteLn (DestinationDir + DirInfo.Name);
  176.                 Assign (F,SourcePath + DirInfo.Name);
  177.                 Rename (F,DestinationDir + DirInfo.Name);
  178.               END; {IF ConfirmOverwrite}
  179.           END; {IF not a directory and not a volume label}
  180.         FindNext (DirInfo);
  181.       END;  {WHILE}
  182.   END; {of procedure MoveByRenaming}
  183.  
  184. PROCEDURE ValidateDestination;
  185.   VAR
  186.     L : integer;
  187.   BEGIN
  188.     IF (Length (DestinationDir) = 2) AND (DestinationDir[2] = ':') THEN
  189.       BEGIN
  190.         DestinationDir := DestinationDir + '\';
  191.         Exit;
  192.       END;
  193.  
  194.     L := Length (DestinationDir) - 1;
  195.  
  196.     IF DirExists (Copy (DestinationDir,1,L)) THEN
  197.       Exit
  198.     ELSE IF DosError = 3 THEN
  199.       BEGIN
  200.         WriteLn;
  201.         WriteLn
  202.           ('Destination directory ',
  203.            DestinationDir,
  204.            ' does not exist');
  205.         WriteLn;
  206.         Halt (2);
  207.       END
  208.     ELSE
  209.       BEGIN
  210.         WriteLn;
  211.         WriteLn
  212.           ('Error accessing drive ', DestinationDrive);
  213.         WriteLn;
  214.         Halt (2);
  215.       END;
  216.   END;    {of procedure ValidateDestination}
  217.  
  218. PROCEDURE ValidateSource;
  219.   VAR
  220.     L          : integer;
  221.   BEGIN
  222.     L := Length (SourcePath) - 1;
  223.  
  224.     IF DirExists (Copy (SourcePath,1,L)) THEN
  225.       BEGIN
  226.         {do nothing}
  227.       END
  228.     ELSE
  229.       BEGIN
  230.         WriteLn;
  231.         WriteLn
  232.           ('Path to source files ',SourcePath,' does not exist');
  233.         WriteLn;
  234.         Halt (3);
  235.       END;
  236.  
  237.     FindFirst (SourceFiles, AnyFile, DirInfo);
  238.     IF DosError = 0 THEN
  239.       BEGIN
  240.         {do nothing}
  241.       END
  242.     ELSE
  243.       IF DosError = 18 THEN
  244.         BEGIN
  245.           WriteLn;
  246.           WriteLn
  247.             ('No files matching ',SourceFiles,' found');
  248.           WriteLn;
  249.           Halt (3);
  250.         END
  251.     ELSE
  252.       BEGIN
  253.         WriteLn;
  254.         WriteLn ('Error accessing drive ',SourceDrive);
  255.         WriteLn;
  256.         Halt (3);
  257.       END;
  258.   END; {of procedure ValidateSource}
  259.  
  260. PROCEDURE GetSourceAndDestination;
  261.   BEGIN
  262.     IF ParamCount < 1 THEN
  263.       ShowCorrectUsage;
  264.  
  265.     CurrentDrive := GetCurrentDrive;
  266.     SourceFiles := ToUpper (ParamStr (1));
  267.  
  268.     IF ParamCount = 2 THEN
  269.       DestinationDir := ToUpper (ParamStr (2))
  270.     ELSE
  271.       GetDir (0,DestinationDir);
  272.  
  273.     IF SourceFiles[2] = ':' THEN
  274.       SourceDrive := Copy (SourceFiles,1,2)
  275.     ELSE
  276.       SourceDrive := CurrentDrive;
  277.  
  278.     FSplit (SourceFiles, SourcePath, SourceName, SourceExt);
  279.     IF SourcePath = '' THEN
  280.       BEGIN
  281.         GetDir (0, SourcePath);
  282.         SourceFiles := SourcePath + '\' + SourceName + SourceExt;
  283.       END;
  284.  
  285.     IF SourcePath[Length (SourcePath)] <> '\' THEN
  286.       SourcePath := SourcePath + '\';
  287.  
  288.     IF DestinationDir[2] = ':' THEN
  289.       DestinationDrive := Copy (DestinationDir,1,2)
  290.     ELSE
  291.       BEGIN
  292.         DestinationDrive := CurrentDrive;
  293.         DestinationDir := DestinationDrive + DestinationDir;
  294.       END;
  295.  
  296.     IF DestinationDir[Length(DestinationDir)] <> '\' THEN
  297.       DestinationDir := DestinationDir + '\';
  298.  
  299.     IF SourceDrive = DestinationDrive THEN
  300.       OnSameDrive := TRUE
  301.     ELSE
  302.       OnSameDrive := FALSE;
  303.   END; {of procedure GetSourceAndDestination}
  304.  
  305. PROCEDURE ShowTitle;
  306.   BEGIN
  307.     WriteLn ('QMOVE - Quick File Move Utility');
  308.     WriteLn ('Public Domain, 1988, by Pat Anderson');
  309.   END;
  310.  
  311. BEGIN {MAIN}
  312.   OverwriteFile := TRUE;
  313.   ShowTitle;
  314.   GetSourceAndDestination;
  315.   ValidateSource;
  316.   ValidateDestination;
  317.   IF OnSameDrive THEN
  318.     MoveByRenaming
  319.   ELSE
  320.     MoveByCopyingAndDeleting;
  321. END.
  322.